"use strict";

var deckScope = null;
function DeckController($scope, hangoutStateUpdateRegistration, hangoutStateWriter, hangoutView) {
    deckScope = $scope;
    $scope.init = function() {
	$scope.deck = [];
	$scope.my_hand = [];
	$scope.deals_so_far = 0;

	if (hangoutView.getFullState() != null) {
	    var full_state = hangoutView.getFullState();
	    if ("deal_count" in full_state) {
		$scope.deals_so_far = parseInt(full_state["deal_count"]);
	    }
	    if ("player_hands" in full_state) {
		var json_hands = full_state["player_hands"];
		var hands = JSON.parse(json_hands);
		$scope.my_hand = hands[hangoutView.getMyId()];
	    }
	    if ("deck" in full_state) {
		$scope.deck = JSON.parse(full_state["deck"]);
	    }
	}
	hangoutStateUpdateRegistration($scope.hangoutStateHandler);
    }

    $scope.hangoutStateHandler = function(state, delta_state) {
	if ("deal_count" in delta_state) {
	    $scope.$apply(function(){$scope.deals_so_far = parseInt(delta_state["deal_count"]);});
	}
	
	var json_hand_var = hangoutView.getMyStateVar("player_hand");
	if (json_hand_var in delta_state) {
	    $scope.$apply(function(){$scope.my_hand = JSON.parse(delta_state[json_hand_var]);});
	}
	
	if ("deck" in delta_state) {
	    $scope.$apply(function(){$scope.deck = JSON.parse(delta_state["deck"]);});
	}
    }
    
    $scope.tryAddWork = function(work_type, work_data) {
	if (hangoutView.iCanAddWork()) {
	    hangoutStateWriter("work_requests_" + hangoutView.getMyId(),
			       JSON.stringify({"type" : work_type, "data" : work_data}));
	} else {
	    console.log("can't add work: ", hangoutView.getMyStateVal("work_requests"));
	}
    }

    $scope.deal = function() {
	$scope.tryAddWork("deal");
    }
    
    $scope.returnToBottom = function(card) {
	$scope.tryAddWork("discard", card);
    }
    
    $scope.keep = function(card) {
	$scope.removeFromDealt(card);
    }
    
    $scope.removeFromDealt = function (card) {
	var i = 0;
	for (i = 0; i < $scope.dealt_cards.length; ++i) {
	    if ($scope.dealt_cards[i] === card) {
		$scope.dealt_cards.splice(i, 1);
		return;
	    }
	}
    }
    $scope.init();
}

DeckController.$inject = ['$scope', 'hangoutStateUpdateRegistration', 'hangoutStateWriter', 'hangoutView'];

function calcMasterCount(hangoutView) {
    var participants = hangoutView.getParticipants();
    var i = 0;
    var master_count = {};
    for (i = 0; i < participants.length; ++i) {
	var believed_master = hangoutView.getStateVal("master_view_" + participants[i].id);
	if (believed_master == null) {
	    continue;
	}
	if (believed_master in master_count) {
	    master_count[believed_master] = master_count[believed_master] + 1;
	} else {
	    master_count[believed_master] = 1;
	}
    }
    return master_count;
}

function BbtmMasterController($scope, hangoutStateUpdateRegistration, hangoutStateWriter, hangoutView) {
    $scope.init = function (apiInitEvent) {
	console.log("init master controller");
	hangoutStateUpdateRegistration($scope.hangoutStateHandler);
	var master_count = calcMasterCount(hangoutView);
	var max_count = 0;
	var max_candidate = null;
	var my_id = hangoutView.getMyId();
	hangoutStateWriter("player_hand_" + my_id, JSON.stringify([]));
	for (var candidate in master_count) {
	    if (master_count[candidate] > max_count) {
		max_count = master_count[candidate];
		max_candidate = candidate;
	    }
	}
	if (candidate == null) {
	    candidate = my_id;
	}
	hangoutStateWriter("master_view_" + my_id, candidate);
    }

    $scope.hangoutStateHandler = function(state, delta_state) {
	console.log("master handler: ", state, delta_state);
	var participants = hangoutView.getParticipants();
	var my_id = hangoutView.getMyId();
	var i = 0;
	var master_count = calcMasterCount(hangoutView);
	var my_believed_master = hangoutView.getMyStateVal("master_view");
	if (master_count[my_believed_master] <= (participants.length / 2)) {
	    // choose new master
	    var new_master = null;
	    for (var master_candidate in master_count) {
		if (master_count[master_candidate] > master_count[my_believed_master]) {
		    new_master = master_candidate;
		} else if (master_count[master_candidate] == master_count[my_believed_master]) {
		    if (rand_range(0,2) == 0) {
			new_master = master_candidate;
		    }
		}
	    }
	    if (new_master != null) {
		hangoutStateWriter("master_view_" + my_id, new_master);
	    } else {
		// force another state update where all participants will re-eval masterhood by setting a junk var.
		hangoutStateWriter("junk", "" + rand_range(0, 99999));
	    }
	}
	if (master_count[my_id] != participants.length) {
	    $scope.stateUpdateInProgress = false;
	    return;
	}

	if (!("deck" in state)) {
	    var DECK_SIZE = 50;
	    var i = 0;
	    var deck = [];
	    for (i = 0; i < DECK_SIZE; ++i) {
		deck.push(i);
	    }
	    shuffle(deck);
	    hangoutStateWriter("deck", JSON.stringify(deck));
	    hangoutStateWriter("deal_count", "0");
	    $scope.stateUpdateInProgress = false;
	    return;
	}

	for (i = 0; i < participants.length; ++i) {
	    var work_req = getWorkRequestFromState(delta_state, participants[i].id);
	    if (work_req == null || work_req == "") {
		continue;
	    }
	    var work_type = work_req["type"];
	    var work_data = work_req["data"];
	    if (work_type == "deal") {
		console.log("Do deal");
		var deck = JSON.parse(state["deck"]);
		if (deck.length > 0) {
		    var card = deck.pop();
		    hangoutStateWriter("deck", JSON.stringify(deck));
		    var player_hand = $scope.getPlayerHand(state, participants[i].id);
		    player_hand.push(card);
		    $scope.setPlayerHand(participants[i].id, player_hand);
		}
		hangoutStateWriter("deal_count", parseInt(state["deal_count"]) + 1 + "");
	    } else if (work_type == "discard") {
		var deck = JSON.parse(state["deck"]);
		deck.splice(0, 0, work_data);
		hangoutStateWriter("deck", JSON.stringify(deck));
		var player_hand = $scope.getPlayerHand(state, participants[i].id);
		for (var card_idx = 0; card_idx < player_hand.length; ++card_idx) {
		    if (player_hand[card_idx] === work_data) {
			player_hand.splice(card_idx, 1);
			$scope.setPlayerHand(participants[i].id, player_hand);
			break;
		    }
		}
	    }
	    hangoutStateWriter("work_requests_" + participants[i].id, JSON.stringify(""));
	}
    }
    
    $scope.getPlayerHand = function(state, player_id) {
	return JSON.parse(state["player_hand_" + player_id]);
    }

    $scope.setPlayerHand = function(player_id, hand) {
	hangoutStateWriter("player_hand_" + player_id, JSON.stringify(hand));
    }
    
    hangoutView.registerApiReadyCallback($scope.init);
}

BbtmMasterController.$inject = ['$scope', 'hangoutStateUpdateRegistration', 'hangoutStateWriter', 'hangoutView'];